﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Animation;

namespace Emilie.Animation.Simple
{
    public static class Opacity
    {
        private static Random r = new Random();

        static void sb_Completed(object sender, object e)
        {
            var s = sender as Storyboard;
            s.Completed -= sb_Completed;
            Base.Unregister(s);
        }

        public static void AddDoubleAnimationFade(this Storyboard _sb, FrameworkElement _target, Double? _from, Double _to, TimeSpan? beginTime, TimeSpan _duration, EasingFunctionBase _easing)
        {
            _sb.AddDoubleAnimation(_target, "(UIElement.Opacity)", _from, _to, beginTime, _duration, _easing);
        }

        /// <summary>
        /// Performs an opacity based Fade animation on a FrameworkElement
        /// </summary>
        /// <param name="_target">FrameworkElement to animate</param>
        /// <param name="_from">Starting opacity. Leave null to use current.</param>
        /// <param name="_to">Ending opacity</param>
        /// <param name="_duration">Length of animation</param>
        /// <param name="_easing">Easing mode to apply to animation. Can be left null for none</param>
        /// <param name="_options">Storyboard options for animation. Can be left null for none</param>
        public static void BeginFade(this FrameworkElement _target, Double? _from, Double _to, TimeSpan _duration, EasingFunctionBase _easing, StoryboardOptions _options)
        {
            Fade(_target, _from, _to, _duration, _easing, _options).Begin();
        }

        /// <summary>
        /// Create a storyboard that performs an opacity based Fade animation on a FrameworkElement
        /// </summary>
        /// <param name="_target">FrameworkElement to animate</param>
        /// <param name="_from">Starting opacity. Leave null to use current.</param>
        /// <param name="_to">Ending opacity</param>
        /// <param name="_duration">Length of animation</param>
        /// <param name="_easing">Easing mode to apply to animation. Can be left null for none</param>
        /// <param name="_options">Storyboard options for animation. Can be left null for none</param>
        /// <returns>Completed storyboard</returns>
        public static Storyboard Fade(FrameworkElement _target, Double? _from, Double _to, TimeSpan _duration, EasingFunctionBase _easing, StoryboardOptions _options)
        {
            Storyboard sb = new Storyboard();                                                               // Create a storyboard
            String ID = Base.GenerateUniqueID() + "OpacityAnimation";                                       // Generate a Unique ID for the storyboard
            _target.Resources.Add(ID, sb);                                                                  // Register Storyboard with parent element

            // ADD THE DOUBLE ANIMATION
            sb.AddDoubleAnimationFade(_target, _from, _to, null, _duration, _easing);

            // FINALIZE STORYBOARD
            Base.ApplyStoryboardOptions(sb, _options);                                                      // Apply storyboard options
            Base.Register(_target, sb, ID);

            return sb;
        }
    }
}
